
mod chess;
mod matcher;
mod server;

use game::chess::{ChessPlayer, ChessRoom, GameStage};
use self::matcher::Queue;
use self::server::GameServer;

use std::sync::mpsc;
use std::thread;
use std::thread::JoinHandle;
use std::time::Duration;
use std::sync::{RwLock, Arc};
use std::collections::HashMap;
use std::net::TcpStream;

use ws::WebSocket;

lazy_static! {
    static ref N_CONNECTIONS: Arc<RwLock<HashMap<u32, WebSocket<TcpStream>>>> = {
        let mut map = Arc::new(RwLock::new(HashMap::<u32, WebSocket<TcpStream>>::new()));
        map
    };
    static ref G_CONNECTIONS: Arc<RwLock<HashMap<u32, WebSocket<TcpStream>>>> = N_CONNECTIONS.clone();
//    static ref HASHMAP: HashMap<u32, &'static str> = {
//        let mut m = HashMap::new();
//        m.insert(0, "foo");
//        m.insert(1, "bar");
//        m.insert(2, "baz");
//        m
//    };
//    static ref COUNT: usize = HASHMAP.len();
}


pub fn run(){
//    let (sender, receiver) = mpsc::sync_channel(10);
//    let ghandle = game_loop(receiver, &G_CONNECTIONS);
//    let nhandle = net_loop(sender, &N_CONNECTIONS);
//    ghandle.join();
//    nhandle.join();
    let addr = "127.0.0.1:8020".parse().unwrap();
    let mut server = GameServer::new(addr);

    let mut rooms = Vec::<ChessRoom>::new();
    let mut queue = Queue::with_capacity(4);

    loop{
        let vec = server.handle();
        for p in vec{
            let ret = queue.player_match(p);
            match ret {
                Some(room) => rooms.push(room),
                None => ()
            }
        }
        let mut index = 0;
        if rooms.len() == 0{
            thread::sleep(Duration::from_millis(500));
        }
        let mut remove = Vec::<usize>::new();
        for room in &mut rooms{
            info!("Play game in room start.....................");
            room.play();
            info!("Play game in room over.....................");
            if room.game_stage() == &GameStage::Over{
                remove.push(index);
            }
            index = index + 1;
            info!("Handle game play in room {}...........", room.id());
        }
        for i in remove{
            rooms.remove(i);
        }
    }
}
//
//pub fn net_loop(sender: mpsc::SyncSender<ChessPlayer>, map: &'static Arc<RwLock<HashMap<u32, WebSocket<TcpStream>>>>) -> JoinHandle<()>{
//    let handle = thread::spawn(move||{
//        let addr = "127.0.0.1:8020".parse().unwrap();
//        let mut server = GameServer::new(addr);
//
//        let mut rooms = Vec::<ChessRoom>::new();
//        let mut queue = Queue::with_capacity(4);
//
//        loop{
//            let vec = server.handle();
//            if 0 == vec.len(){
//                info!("Receive no player, net thread will sleep 1000ms.");
//                thread::sleep(Duration::from_millis(1000));
//            }else {
//                for p in vec{
//                    sender.try_send(p);
//                    let ret = queue.player_match(p, map);
//                    match ret {
//                        Some(room) => rooms.push(room),
//                        None => ()
//                    }
//                }
//                info!("Send players to game thread. count = {}", 1);
//            }
//        }
//        info!("Net thread stop.");
//    });
//    handle
//}
//
/////由一个单独线程处理。通过channel与外界通信。
///// 游戏循环。
///// 还要考虑一下一盘游戏结束后，玩家连接该怎么处理。是断开Websocket连接呢，还是保持？
///// 断开连接。重新开始游戏则重新连接。
//pub fn game_loop(receiver: mpsc::Receiver<ChessPlayer>, map: &'static Arc<RwLock<HashMap<u32, WebSocket<TcpStream>>>>) -> JoinHandle<()>{
//    let handle = thread::spawn( move||{
//        let mut rooms = Vec::<ChessRoom>::new();
//        let mut queue = Queue::with_capacity(4);
//        info!("Game loop running................");
//        loop{
//            let message = receiver.try_recv();
//            match message {
//                Ok(p) => {
//                    info!("Get a player, id = {}", p.id());
//                    let ret = queue.player_match(p, map);
//                    match ret {
//                        Some(room) => {rooms.push(room);},
//                        None => ()
//                    }
//                },
//                Err(e) => ()
//            }
//            let mut index = 0;
//            let mut remove = Vec::<usize>::new();
//            for room in &mut rooms{
//                info!("Play game in room start.....................");
//                room.play(map);
//                info!("Play game in room over.....................");
//                if room.game_stage() == &GameStage::Over{
//                    remove.push(index);
//                }
//                index = index + 1;
//                info!("Handle game play in room {}...........", room.id());
//            }
//            for i in remove{
//                rooms.remove(i);
//            }
//            thread::sleep(Duration::from_millis(1000));
//        }
//        info!("game loop over........................");
//    });
//    handle
//}

///json消息处理结果
pub enum Result{
    Ok(u32),
    Error(u32)
}